/**
 * @author Ahammer
 * @date 2010 05
 */

/*
 * This is an implementation of the ImageJ ImageStabilizer plugin by Kang Li
 * K. Li, "The image stabilizer plugin for ImageJ," http://www.cs.cmu.edu/~kangli/code/Image_Stabilizer.html
 * This plugin stabilizes jittery image stacks using the Lucas-Kanade algorithm. It supports both grayscale and color images.
 */

/*
 * This file is part of Iqm.
 * Copyright (c) 2010-2011 Helmut Ahammer
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package op;

import ij.ImagePlus;
import ij.process.ImageProcessor;
import ijplugin.Image_Stabilizer;
import ijplugin.Image_Stabilizer_Log_Applier;
import ijplugin.IqmImage_Stabilizer;
import ijplugin.bUnwarpJ_;
import java.awt.Image;
import java.awt.image.DataBuffer;
import java.awt.image.SampleModel;
import java.awt.image.renderable.ParameterBlock;
import javax.media.jai.JAI;
import javax.media.jai.ParameterBlockJAI;
import javax.media.jai.PlanarImage;

import main.Board;

/**
 * This is the main image processing class
 * There exist two approaches:
 * A user defined JAI operator is just called 
 * or:
 * The actual processing is implemented in this class 
 */
public class IqmImgStabilizerOperator{ 


  public IqmImgStabilizerOperator() {
	  //WARNING: Don't declare fields here
	  //Fields declared here aren't thread safe!   
  }
  /**
   * 
   * @param ParametrBlockJAI pb
   */
  public Object run(ParameterBlockJAI pbJAI){
	  Object ob = null;
	  //ob = JAI.create("IqmImgStabilizer".toLowerCase(), pb, null);  
	  
	  PlanarImage pi1  = (PlanarImage) pbJAI.getSource(0);	
	  PlanarImage pi2  = (PlanarImage) pbJAI.getSource(1);	
	  int regMode      = pbJAI.getIntParameter("RegMode");
	  int pyrLevels    = pbJAI.getIntParameter("PyrLevels");
	  float tempUpCo   = pbJAI.getFloatParameter("TempUpCo");
	  float maxIt      = pbJAI.getFloatParameter("MaxIt");
	  float errTol     = pbJAI.getFloatParameter("ErrTol");
	  int logCo        = pbJAI.getIntParameter("LogCo");
	  
	  Image image1 = pi1.getAsBufferedImage();
	  Image image2 = pi2.getAsBufferedImage();
	  SampleModel sampleModel = pi1.getSampleModel();
	  String imgName = (String) pi2.getProperty("image_name");
	  String fileName = (String) pi2.getProperty("file_name");
	  ImagePlus targetImPlus = new ImagePlus("", image1);
	  ImagePlus sourceImPlus = new ImagePlus("", image2);
	  //ImageProcessor targetMskIP = targetImPlus.getProcessor();
	  //ImageProcessor sourceMskIP = sourceImPlus.getProcessor();
		 
	  //RenderingHints rh = new RenderingHints(JAI.KEY_BORDER_EXTENDER, BorderExtender.createInstance(BorderExtender.BORDER_COPY));	
	  //RenderingHints rh = null;	
	  //ParameterBlock pb = new ParameterBlock();
	  
	  Board.appendTexln("IqmImgStabilizerOperator: Stabilization, please wait.......");
	  	 
	  IqmImage_Stabilizer imgSt = new IqmImage_Stabilizer();
	  ImagePlus imp = new ImagePlus();
	  imgSt.processIqm(targetImPlus, sourceImPlus, regMode, pyrLevels, tempUpCo, maxIt, errTol);
	  imp = imgSt.getStabilizedImage();
  
	  //int bytesPerPixel = imp.getBytesPerPixel();
	  //System.out.println("IqmImgStabilizerOperator: bytesPerPixel: "+bytesPerPixel );
//	  IJ.run(imp, "RGB Color", "");
//	  imp.updateImage();
//	  if (pi1.getNumBands() == 1){	 //grey
//		  IJ.run(imp, "8-bit", "");
//	  }	  
	  imp.updateImage();
	  //Image imageResult = imp.getBufferedImage();
	  Image imageResult = imp.getImage();
	  ob = JAI.create("AWTImage", imageResult);	
      
//	  if (((PlanarImage)ob).getColorModel() instanceof IndexColorModel){
//		  IndexColorModel icm = (IndexColorModel)((PlanarImage)ob).getColorModel();
//	      byte[][] data = new byte[3][icm.getMapSize()];
//	      icm.getReds(data[0]);
//	      icm.getGreens(data[1]);
//	      icm.getBlues(data[2]);
//	      LookupTableJAI lut = new LookupTableJAI(data);
//	
//	      ParameterBlock pb = new ParameterBlock();
//		  pb.addSource(ob);
//		  pb.add(lut);
//	      ob = JAI.create("lookup", pb);  //RGB image           
//	  }
	  
	  //Folgendes geht auch
//	  ImageLayout layout = new ImageLayout();
//	  ColorModel cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[] { 8, 8, 8 }, false, true, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
//	  layout.setColorModel(cm);
//	  RenderingHints hints = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, layout);
//	  ParameterBlockJAI pbFormat = new ParameterBlockJAI("format");
//	  pbFormat.addSource(ob); 
//	  ob = JAI.create("format", pbFormat, hints);
	 
	  ParameterBlockJAI pbFormat = new ParameterBlockJAI("format");
	  pbFormat.addSource(ob);
	  pbFormat.setParameter("dataType", DataBuffer.TYPE_BYTE);
	  //ob = JAI.create("format", pbFormat, hints);
	  ob = JAI.create("format", pbFormat);

//      if (pi1.getNumBands() == 1){	 //grey
//		  double[][] matrix = {{ 0.114, 0.587, 0.299, 0 }};
//	
//		  ParameterBlock pb = new ParameterBlock();
//		  pb.addSource(ob);
//		  pb.add(matrix);
//		  ob = JAI.create("bandcombine", pb, null);
//      }
  
	  ((PlanarImage)ob).setProperty("image_name", imgName);
	  ((PlanarImage)ob).setProperty("file_name", fileName);	
	
	  return ob;
  }
}
